package com.ecoolex.hotel.saas.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.RandomUtil;
import com.ecoolex.hotel.saas.core.dao.PresaleCouponOrderAfterSalesDAO;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrder;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderAfterSales;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderAfterSales.Column;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderAfterSalesExample;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderAfterSalesExample.Criteria;
import com.ecoolex.hotel.saas.enums.PresaleCouponOrderAfterSalesRecordType;
import com.ecoolex.hotel.saas.enums.PresaleCouponOrderAfterSalesStatus;
import com.ecoolex.hotel.saas.enums.PresaleCouponOrderAfterSalesType;
import com.ecoolex.hotel.saas.pojo.QueryPresaleCouponOrderAfterSalesDTO;

import java.time.Instant;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PresaleCouponOrderAfterSalesManager {
	
    @Autowired
    private PresaleCouponOrderAfterSalesDAO dao;
    
    @Autowired
    private PresaleCouponOrderManager orderManager;
    
    @Autowired
    private PresaleCouponOrderAfterSalesRecordManager recordMageger;
    
    public PresaleCouponOrderAfterSales getAfterSales(Integer afterSalesId) {
		return dao.selectByPrimaryKey(afterSalesId);
	}

	public Pagination<PresaleCouponOrderAfterSales> queryAfterSales(QueryPresaleCouponOrderAfterSalesDTO query, Page page) {
		
		return Pagination.create(page, 
			dao.count(query), 
			() -> dao.query(query, page));
	}

	public Pagination<PresaleCouponOrderAfterSales> queryAfterSalesForUser(Integer storeId, Integer userId, Page page) {
		PresaleCouponOrderAfterSalesExample example = new PresaleCouponOrderAfterSalesExample();
		Criteria criteria = example.createCriteria();
		criteria.andStoreIdEqualTo(storeId).andUserIdEqualTo(userId).andDeletedEqualTo(PresaleCouponOrderAfterSales.NOT_DELETED);
		example.setOffset(page.getFirstIndex());
		example.setRows(page.getPageSize());
		example.orderBy(Column.createTime.desc());
		return Pagination.create(page, 
			dao.countByExample(example),
			() -> dao.selectByExample(example));
	}
	
	public PresaleCouponOrderAfterSales getLastestByOrderId(Integer orderId) {
		PresaleCouponOrderAfterSalesExample example = new PresaleCouponOrderAfterSalesExample();
		Criteria criteria = example.createCriteria();
		criteria.andOrderIdEqualTo(orderId);
		example.orderBy(Column.createTime.desc());
		example.limit(1);
		return dao.selectOneByExample(example);
	}

	@Transactional
	public PresaleCouponOrderAfterSales agreeRefund(PresaleCouponOrderAfterSales afterSales, String updateUser){
		afterSales.setStatus(PresaleCouponOrderAfterSalesStatus.SUCCESS.real());
		afterSales.setUpdateUser(updateUser);
		afterSales.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(afterSales, Column.status,Column.updateUser,Column.updateTime);
		orderManager.agreeRefund(afterSales.getOrderId(), updateUser);
		//售后记录
		recordMageger.create(afterSales.getAfterSalesId(),
			afterSales.getOrderId(), 
			PresaleCouponOrderAfterSalesRecordType.AGREE_REFUND, 
			null, 
			null, 
			updateUser);
		return afterSales;
	}

	@Transactional
	public PresaleCouponOrderAfterSales refuseRefund(PresaleCouponOrderAfterSales afterSales, String updateUser){
		afterSales.setStatus(PresaleCouponOrderAfterSalesStatus.CLOSE.real());
		afterSales.setUpdateUser(updateUser);
		afterSales.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(afterSales, Column.status,Column.updateUser,Column.updateTime);
		orderManager.refuseRefund(afterSales.getOrderId(), updateUser);
		//售后记录
		recordMageger.create(afterSales.getAfterSalesId(),
			afterSales.getOrderId(), 
			PresaleCouponOrderAfterSalesRecordType.REFUSE_REFUND, 
			afterSales.getAuditOpinion(), 
			null, 
			updateUser);
		return afterSales;
	}
	
	@Transactional
	public PresaleCouponOrderAfterSales cancelApply(PresaleCouponOrderAfterSales afterSales, String updateUser){
		BizAssert.isTrue(PresaleCouponOrderAfterSalesStatus.canDealWith(afterSales.getStatus()),ResultCode.BIZ.build(10), "售后单状态无法取消");
		afterSales.setStatus(PresaleCouponOrderAfterSalesStatus.CLOSE.real());
		afterSales.setUpdateUser(updateUser);
		afterSales.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(afterSales, Column.status,Column.updateUser,Column.updateTime);
		orderManager.cancelAfterSales(afterSales.getOrderId(), updateUser);
		//售后记录
		recordMageger.create(afterSales.getAfterSalesId(),
			afterSales.getOrderId(), 
			PresaleCouponOrderAfterSalesRecordType.CANCEL, 
			null, 
			null, 
			updateUser);
		return afterSales;
	}

	public PresaleCouponOrderAfterSales delete(PresaleCouponOrderAfterSales afterSales, String updateUser){
		BizAssert.isTrue(PresaleCouponOrderAfterSalesStatus.canDelete(afterSales.getStatus()),ResultCode.BIZ.build(10), "售后单状态无法删除");
		afterSales.setDeleted(PresaleCouponOrderAfterSales.IS_DELETED);
		afterSales.setUpdateUser(updateUser);
		afterSales.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(afterSales, Column.deleted,Column.updateUser,Column.updateTime);
		return afterSales;
	}
    
    public PresaleCouponOrderAfterSales create(PresaleCouponOrder order, PresaleCouponOrderAfterSalesType type,
    	PresaleCouponOrderAfterSalesStatus status,String remark,String evidenceImage,String auditOpinion,
    	String createUser) {
    	PresaleCouponOrderAfterSales afterSales = new PresaleCouponOrderAfterSales();
    	afterSales.setAfterSalesNo(afterSalesNo());
    	afterSales.setOrderId(order.getOrderId());
    	afterSales.setStoreId(order.getStoreId());
    	afterSales.setUserId(order.getUserId());
    	afterSales.setType(type.real());
    	afterSales.setStatus(status.real());
    	afterSales.setRemark(remark);
    	afterSales.setEvidenceImage(evidenceImage);
    	afterSales.setAuditOpinion(auditOpinion);
    	afterSales.setRefundPrice(order.getRealPrice());
    	afterSales.setDeleted(PresaleCouponOrderAfterSales.NOT_DELETED);
    	afterSales.setCreateUser(createUser);
    	afterSales.setCreateTime(Date.from(Instant.now()));
    	afterSales.setUpdateUser(createUser);
    	afterSales.setUpdateTime(Date.from(Instant.now()));
    	dao.insert(afterSales);
    	return afterSales;
    }
    
    private String afterSalesNo() {
    	String afterSalesNo = RandomUtil.randomInt(18);
    	PresaleCouponOrderAfterSales old = getByAfterSalesNo(afterSalesNo);
		if(Check.notNull(old)) {
			return afterSalesNo();
		}
		return afterSalesNo;
    }
    
    public PresaleCouponOrderAfterSales getByAfterSalesNo(String afterSalesNo){
    	PresaleCouponOrderAfterSalesExample example = new PresaleCouponOrderAfterSalesExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andAfterSalesNoEqualTo(afterSalesNo).andDeletedEqualTo(PresaleCouponOrderAfterSales.NOT_DELETED);
    	return dao.selectOneByExample(example);
    }
    
    public void updateAfterSalesStatus(String orderNo,Integer status,String updateUser) {
    	PresaleCouponOrder order = orderManager.getByOrderNo(orderNo);
    	PresaleCouponOrderAfterSales afterSales = new PresaleCouponOrderAfterSales();
    	afterSales.setStatus(status);
    	afterSales.setUpdateUser(updateUser);
    	afterSales.setUpdateTime(Date.from(Instant.now()));
    	
    	PresaleCouponOrderAfterSalesExample example = new PresaleCouponOrderAfterSalesExample();
    	example.createCriteria().andOrderIdEqualTo(order.getOrderId())
    	.andTypeEqualTo(PresaleCouponOrderAfterSalesType.REFUND.real())
    	.andStatusEqualTo(PresaleCouponOrderAfterSalesStatus.WAIT.real());
    	
    	dao.updateByPrimaryKeySelective(afterSales, Column.status,Column.updateUser,Column.updateTime);
    }
}